Pressidian
花园入口
笔记
项目
关于
实验室
GitHub
花园入口
笔记
项目
关于
实验室
GitHub

KNOWLEDGE PATHS

笔记库
当前位置
笔记库/学习/408/数据结构

8.1 排序基本概念

7 分钟阅读 · Note

目录树 578 篇

          • 3.1 栈
          • 4.1 串定义与基本操作
          • 5.1 树
          • 6.1 图的基本概念
          • 7.1 查找的基本概念
          • 8.1 排序基本概念
          • 第二章 线性表
          • 第一章 绪论
      • 论文
    • 笔记目录
    • CLAUDE.md
    • Vue 组件与 Render 函数

关联笔记 6

↗3.1 栈同一路径↗4.1 串定义与基本操作同一路径↗5.1 树同一路径↗6.1 图的基本概念同一路径↗7.1 查找的基本概念同一路径↗第二章 线性表同一路径
  • 8.1 排序基本概念

8.1 排序基本概念

稳定性

![Pasted image 20251102185141](../../../_assets/81879c6-Pasted image 20251102185141.png)

分类

![Pasted image 20251102185109](../../../_assets/d6666f8-Pasted image 20251102185109.png)

8.2 插入与希尔

8.2.1 插入排序

![Pasted image 20251103143724](../../../_assets/be1f886-Pasted image 20251103143724.png)

代码实现

每次将大于待插入元素的前面的元素后移一位,再将待插入元素移入空出的位置: ![Pasted image 20251103144227](../../../_assets/7dde8fe-Pasted image 20251103144227.png) 空间复杂度:O(1),时间复杂度:O(n^2),稳定。在待排序的记录基本有序的时候,时间复杂度能达到O(1)的级别。

优化

在待插入元素的前面的部分是有序的,可以使用折半查找优化: ![Pasted image 20251103145002](../../../_assets/7f8ed8a-Pasted image 20251103145002.png) ![Pasted image 20251103145042](../../../_assets/c3598fc-Pasted image 20251103145042.png) ![Pasted image 20251103145127](../../../_assets/cce519d-Pasted image 20251103145127.png) 此时low在high的右侧,停止折半查找,high右侧的元素均大于i所指元素,low左侧则均小于。在low和high中间的位置就是待插入元素的插入位置: ![Pasted image 20251103145257](../../../_assets/4c32cb0-Pasted image 20251103145257.png) 特殊的,在这种情况下,不应该停止查找,而应该是在右侧继续寻找60,确保算法的稳定性: ![Pasted image 20251103145651](../../../_assets/1a74605-Pasted image 20251103145651.png) ![Pasted image 20251103145812](../../../_assets/6969104-Pasted image 20251103145812.png) 这时,插入60就能够保证算法的稳定性: ![Pasted image 20251103145845](../../../_assets/dcd9a88-Pasted image 20251103145845.png) ![Pasted image 20251103150256](../../../_assets/e822663-Pasted image 20251103150256.png)

8.2.2 希尔排序

将表中的元素拆分为多个子表,将子表中的元素排序,最后整体有序。

![Pasted image 20251103151307](../../../_assets/bae4d80-Pasted image 20251103151307.png) ![Pasted image 20251103151347](../../../_assets/9889e88-Pasted image 20251103151347.png) ![Pasted image 20251103151522](../../../_assets/d006965-Pasted image 20251103151522.png) ![Pasted image 20251103151545](../../../_assets/b03f7ab-Pasted image 20251103151545.png) 在这一次排序中,表中的数据就已经基本有序: ![Pasted image 20251103151630](../../../_assets/2fd1a77-Pasted image 20251103151630.png) ![Pasted image 20251103151712](../../../_assets/95ea2cf-Pasted image 20251103151712.png)

代码实现

![Pasted image 20251103152435](../../../_assets/9a3f4e2-Pasted image 20251103152435.png) 空间复杂度:O(1),时间复杂度:在O(n^1.3)到O(n^2),暂时无法用数学形式证明。不稳定。并且只能基于线性表实现。

8.3 交换排序

8.3.1 冒泡排序

![Pasted image 20251103153829](../../../_assets/978a092-Pasted image 20251103153829.png) ![Pasted image 20251103153859](../../../_assets/2ebff71-Pasted image 20251103153859.png) ![Pasted image 20251103153950](../../../_assets/881e75e-Pasted image 20251103153950.png) ![Pasted image 20251103154029](../../../_assets/cdcd887-Pasted image 20251103154029.png)

算法实现

若某一趟排序过程没有交换,就说明已经有序,可以提前结束: ![Pasted image 20251103154257](../../../_assets/a44c8a3-Pasted image 20251103154257.png)

空间复杂度:O(1),时间复杂度:O(n^2),稳定。 ![Pasted image 20251103154658](../../../_assets/8037c5c-Pasted image 20251103154658.png)

8.3.1 快速排序

![Pasted image 20251103160249](../../../_assets/3933bf5-Pasted image 20251103160249.png) ![Pasted image 20251103160517](../../../_assets/39b1f9f-Pasted image 20251103160517.png) ![Pasted image 20251103160538](../../../_assets/a7dd2d8-Pasted image 20251103160538.png) ![Pasted image 20251103160556](../../../_assets/79e8f8b-Pasted image 20251103160556.png) ![Pasted image 20251103160609](../../../_assets/c9d4872-Pasted image 20251103160609.png) ![Pasted image 20251103160626](../../../_assets/7993e81-Pasted image 20251103160626.png) 将基准元素左右两侧的子表继续快排,直到左右子表就剩一个元素的时候

代码实现(重点)

![Pasted image 20251103160903](../../../_assets/b4af98c-Pasted image 20251103160903.png)

空间复杂度:O(递归层数),时间复杂度:O(n * 递归层数),不稳定。递归层数的数量级在log n与n之间。理想情况下,空间复杂度:O(log n),时间复杂度:O(nlog n) ![Pasted image 20251103163056](../../../_assets/3fe373f-Pasted image 20251103163056.png)

对于本有序的序列,快排的性能最差。可以随机选取枢轴元素来解决这个问题。

8.4 选择排序

8.4.1 简单选择排序(暴力)

在待排序的元素中选着最小的加入有序队列

代码实现

![Pasted image 20251103163815](../../../_assets/22a8199-Pasted image 20251103163815.png) 空间复杂度:O(1),时间复杂度:O(n^2),不稳定。

8.4.2 堆排序

![Pasted image 20251103171311](../../../_assets/2faeeb7-Pasted image 20251103171311.png) 被选出的堆顶元素,就不会再继续参与排序(已确定)

代码实现

![Pasted image 20251103171801](../../../_assets/7ce7675-Pasted image 20251103171801.png) 建堆过程时间复杂度:O(n),排序整体时间复杂度:O(nlog n),空间复杂度:O(1),不稳定

堆

![Pasted image 20251103165446](../../../_assets/8650e65-Pasted image 20251103165446.png) 逻辑上是一棵顺序存储的完全二叉树,大根堆就是根节点大于左右子树。

将初始的序列建立为一个大根堆,再使用选择排序就能提高效率。 ![Pasted image 20251103170150](../../../_assets/59cbc1e-Pasted image 20251103170150.png)

堆的代码实现

![Pasted image 20251103170622](../../../_assets/6144124-Pasted image 20251103170622.png)

堆插入与删除

![Pasted image 20251103173416](../../../_assets/a4e82c9-Pasted image 20251103173416.png) ![Pasted image 20251103173627](../../../_assets/b377712-Pasted image 20251103173627.png)

8.5

8.5.1 归并排序

![Pasted image 20251103191125](../../../_assets/30ccc11-Pasted image 20251103191125.png)

代码实现

![Pasted image 20251103191743](../../../_assets/3be2019-Pasted image 20251103191743.png)

![Pasted image 20251103192432](../../../_assets/311a1a5-Pasted image 20251103192432.png) 时间复杂度:O(nlog n),空间复杂度:O(n)(其中包括辅助数组n和递归栈所占用的空间log n),稳定的。

归并

将多个有序的序列合并 ![Pasted image 20251103190045](../../../_assets/aa31d9b-Pasted image 20251103190045.png)

考试通常是二路,手算。上例是二路归并,下面为四路: ![Pasted image 20251103190716](../../../_assets/c37678d-Pasted image 20251103190716.png)

8.5.2 基数排序

将关键字的每个位数取出排序后,再取高位再排序,直到全部的位都被排序过 ![Pasted image 20251103193727](../../../_assets/f4ed8ae-Pasted image 20251103193727.png) ![Pasted image 20251103193651](../../../_assets/68267d2-Pasted image 20251103193651.png) ![Pasted image 20251103193916](../../../_assets/1f52b2f-Pasted image 20251103193916.png) ![Pasted image 20251103194045](../../../_assets/2131ba8-Pasted image 20251103194045.png) ![Pasted image 20251103194202](../../../_assets/23e05fa-Pasted image 20251103194202.png) ![Pasted image 20251103194249](../../../_assets/1475c48-Pasted image 20251103194249.png) ![Pasted image 20251103194333](../../../_assets/421872e-Pasted image 20251103194333.png) 通常基于链式存储实现,空间复杂度:O(每位可能取值的个数),时间复杂度:O(分配的次数 * (关键字的位数 + 每位可能取值的个数)),稳定的。

对于要排序的数据可以拆分、分组不太多的时候时候使用: ![Pasted image 20251103195835](../../../_assets/3010d6a-Pasted image 20251103195835.png)

8.5.3 计数排序

8.7 外部排序

8.7.1 基础概念

![Pasted image 20251108153246](../../../_assets/4d5422e-Pasted image 20251108153246.png)

构造初始归并段

将第一块与第二块的内容读入内存,进行内部排序,再写入内存变为一个归并段: ![Pasted image 20251108153650](../../../_assets/b844ca8-Pasted image 20251108153650.png)

第一趟归并

将归并段进行归并: ![Pasted image 20251108153909](../../../_assets/0a1402f-Pasted image 20251108153909.png) ![Pasted image 20251108154021](../../../_assets/b7252b4-Pasted image 20251108154021.png)

第二趟归并

![Pasted image 20251108154156](../../../_assets/ac8393d-Pasted image 20251108154156.png)

时间开销分析

![Pasted image 20251108154418](../../../_assets/f019fc8-Pasted image 20251108154418.png) 时间开销=读写时间+排序时间(构造初始归并段)+归并时间

减少归并的次数就能减少读写的时间: ![Pasted image 20251108155045](../../../_assets/2d81df4-Pasted image 20251108155045.png)

8.7.2 败者树

![Pasted image 20251108155324](../../../_assets/0a31997-Pasted image 20251108155324.png) 使用多路归并时,对比的次数会变多,可以使用败者树优化

![Pasted image 20251108160637](../../../_assets/b95f987-Pasted image 20251108160637.png) ![Pasted image 20251108160729](../../../_assets/a760e04-Pasted image 20251108160729.png) 初始构造时对比k-1次,之后使用败者树最少可以对比log k向上取整的次数,比k-1要少的多

8.7.3 置换-选择排序

优化构造初始归并段的过程,来构建更长的初始归并段: ![Pasted image 20251108162054](../../../_assets/5305196-Pasted image 20251108162054.png)

将比minmax更大的最小值输出,直到wa中不能再输出,就生成一个新的归并段: ![Pasted image 20251108162221](../../../_assets/fe5cf0a-Pasted image 20251108162221.png)

8.7.4 最佳归并树

使用置换-选择排序算法生成的归并段长度不一,每次都要读写每个段的长度: ![Pasted image 20251108162604](../../../_assets/95ff68d-Pasted image 20251108162604.png)

使用哈夫曼树来得到wpl最小的树: ![Pasted image 20251108162745](../../../_assets/e78d54b-Pasted image 20251108162745.png)

构造3路归并的最佳归并树: ![Pasted image 20251108162951](../../../_assets/3c0fe74-Pasted image 20251108162951.png)

如果无法构造k叉归并树: ![Pasted image 20251108163232](../../../_assets/ee2786d-Pasted image 20251108163232.png) ![Pasted image 20251108163732](../../../_assets/afad852-Pasted image 20251108163732.png)